const fs = require('fs-extra');
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');
const dependencyResolver = require('./dependencyResolver');

const execAsync = promisify(exec);

/**
 * 跳过问题依赖构建管理器
 * 专门处理node-sass、nodejieba等难以编译的依赖
 */
class SkipBuildManager {
  constructor() {
    // 已知的问题依赖及其替代方案
    this.problematicDeps = {
      'node-sass': {
        replacement: 'sass',
        reason: 'node-sass在新版Node中有兼容问题',
        action: 'replace'
      },
      'nodejieba': {
        replacement: null,
        reason: '中文分词库，编译复杂',
        action: 'optional'
      },
      'node-gyp': {
        replacement: null,
        reason: '原生模块编译工具',
        action: 'skip'
      },
      'fsevents': {
        replacement: null,
        reason: 'macOS文件监听，可选依赖',
        action: 'optional'
      }
    };
  }

  /**
   * 分析项目中的问题依赖
   */
  async analyzeProblematicDeps(projectPath) {
    const packagePath = path.join(projectPath, 'package.json');
    
    if (!await fs.pathExists(packagePath)) {
      return { hasProblems: false, issues: [] };
    }

    const pkg = await fs.readJson(packagePath);
    const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
    
    const issues = [];
    
    for (const [depName, depInfo] of Object.entries(this.problematicDeps)) {
      if (allDeps[depName]) {
        issues.push({
          name: depName,
          version: allDeps[depName],
          ...depInfo
        });
      }
    }

    return {
      hasProblems: issues.length > 0,
      issues,
      totalDeps: Object.keys(allDeps).length
    };
  }

  /**
   * 修复package.json中的问题依赖
   */
  async fixPackageJson(projectPath) {
    const packagePath = path.join(projectPath, 'package.json');
    const pkg = await fs.readJson(packagePath);
    
    let modified = false;
    const changes = [];

    // 处理dependencies
    if (pkg.dependencies) {
      for (const [depName, depInfo] of Object.entries(this.problematicDeps)) {
        if (pkg.dependencies[depName]) {
          if (depInfo.action === 'replace' && depInfo.replacement) {
            // 替换依赖
            pkg.dependencies[depInfo.replacement] = '^1.0.0'; // 使用合理的版本
            delete pkg.dependencies[depName];
            changes.push(`替换 ${depName} → ${depInfo.replacement}`);
            modified = true;
          } else if (depInfo.action === 'optional') {
            // 移到optionalDependencies
            pkg.optionalDependencies = pkg.optionalDependencies || {};
            pkg.optionalDependencies[depName] = pkg.dependencies[depName];
            delete pkg.dependencies[depName];
            changes.push(`移动 ${depName} 到可选依赖`);
            modified = true;
          }
        }
      }
    }

    // 处理devDependencies
    if (pkg.devDependencies) {
      for (const [depName, depInfo] of Object.entries(this.problematicDeps)) {
        if (pkg.devDependencies[depName]) {
          if (depInfo.action === 'replace' && depInfo.replacement) {
            pkg.devDependencies[depInfo.replacement] = '^1.0.0';
            delete pkg.devDependencies[depName];
            changes.push(`替换 ${depName} → ${depInfo.replacement} (dev)`);
            modified = true;
          } else if (depInfo.action === 'optional') {
            delete pkg.devDependencies[depName];
            changes.push(`删除开发依赖 ${depName}`);
            modified = true;
          }
        }
      }
    }

    // 添加构建配置以忽略可选依赖错误
    if (!pkg.scripts) pkg.scripts = {};
    
    if (modified) {
      // 备份原始package.json
      await fs.copy(packagePath, `${packagePath}.backup`);
      
      // 添加忽略可选依赖的安装脚本
      if (!pkg.scripts.install) {
        pkg.scripts.install = 'npm install --ignore-optional';
      }
      
      // 保存修改后的package.json
      await fs.writeJson(packagePath, pkg, { spaces: 2 });
      
      console.log('📦 package.json修复完成:');
      changes.forEach(change => console.log(`  - ${change}`));
    }

    return { modified, changes };
  }

  /**
   * 使用强制安装策略
   */
  async installWithForce(projectPath, nodeVersion = 'node14') {
    try {
      console.log('💪 使用强制安装策略...');
      
      // 检查包管理器
      let packageManager = 'npm';
      let installCommand;
      
      if (await fs.pathExists(path.join(projectPath, 'yarn.lock'))) {
        packageManager = 'yarn';
        installCommand = 'yarn install --ignore-optional --ignore-engines --force';
      } else if (await fs.pathExists(path.join(projectPath, 'pnpm-lock.yaml'))) {
        packageManager = 'pnpm';
        installCommand = 'pnpm install --ignore-optional --force';
      } else {
        // 使用npm的强制安装命令
        installCommand = 'npm install --legacy-peer-deps --force --ignore-optional --ignore-engines --no-audit --no-fund';
      }
      
      // 设置环境变量
      const env = {
        ...process.env,
        SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: 'true',
        SASS_BINARY_SITE: 'https://npmmirror.com/mirrors/node-sass',
        PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true',
        PYTHON: '/usr/bin/python3',
        npm_config_optional: 'false',
        npm_config_legacy_peer_deps: 'true',
        npm_config_force: 'true'
      };
      
      const { stdout, stderr } = await execAsync(installCommand, {
        cwd: projectPath,
        timeout: 900000, // 15分钟 (强制安装可能更慢)
        env
      });
      
      console.log('✅ 依赖安装完成 (强制策略)');
      return { success: true, stdout, stderr, method: 'force' };
      
    } catch (error) {
      console.error('强制安装失败:', error);
      
      // 如果强制安装失败，尝试更激进的清理和重装
      console.log('🔄 尝试清理重装...');
      return await this.installWithCleanReinstall(projectPath, nodeVersion);
    }
  }

  /**
   * 清理重装策略 (最后的救命稻草)
   */
  async installWithCleanReinstall(projectPath, nodeVersion = 'node14') {
    try {
      console.log('🧹 执行清理重装...');
      
      // 清理所有可能的缓存和锁文件
      const cleanPaths = [
        'node_modules',
        'package-lock.json', 
        'yarn.lock',
        'pnpm-lock.yaml',
        '.npm',
        '.yarn'
      ];
      
      for (const cleanPath of cleanPaths) {
        const fullPath = path.join(projectPath, cleanPath);
        if (await fs.pathExists(fullPath)) {
          await fs.remove(fullPath);
          console.log(`🗑️  清理 ${cleanPath}`);
        }
      }
      
      // 使用最激进的安装命令
      const installCommand = 'npm install --legacy-peer-deps --force --ignore-optional --ignore-engines --no-audit --no-fund --prefer-offline';
      
      const env = {
        ...process.env,
        SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: 'true',
        SASS_BINARY_SITE: 'https://npmmirror.com/mirrors/node-sass',
        PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true',
        PYTHON: '/usr/bin/python3',
        npm_config_optional: 'false',
        npm_config_legacy_peer_deps: 'true',
        npm_config_force: 'true',
        npm_config_prefer_offline: 'true'
      };
      
      const { stdout, stderr } = await execAsync(installCommand, {
        cwd: projectPath,
        timeout: 1200000, // 20分钟
        env
      });
      
      console.log('✅ 清理重装完成');
      return { success: true, stdout, stderr, method: 'clean-reinstall' };
      
    } catch (error) {
      console.error('清理重装失败:', error);
      throw error;
    }
  }

  /**
   * 使用忽略策略安装依赖
   */
  async installWithSkip(projectPath, nodeVersion = 'node14') {
    try {
      console.log('📦 使用跳过策略安装依赖...');
      
      // 检查包管理器
      let packageManager = 'npm';
      let installCommand;
      
      if (await fs.pathExists(path.join(projectPath, 'yarn.lock'))) {
        packageManager = 'yarn';
        installCommand = 'yarn install --ignore-optional --ignore-engines';
      } else if (await fs.pathExists(path.join(projectPath, 'pnpm-lock.yaml'))) {
        packageManager = 'pnpm';
        installCommand = 'pnpm install --ignore-optional';
      } else {
        installCommand = 'npm install --ignore-optional --ignore-engines --no-audit --no-fund';
      }
      
      // 设置环境变量以跳过问题依赖的编译
      const env = {
        ...process.env,
        SKIP_SASS_BINARY_DOWNLOAD_FOR_CI: 'true',
        SASS_BINARY_SITE: 'https://npmmirror.com/mirrors/node-sass',
        PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true',
        PYTHON: '/usr/bin/python3',
        npm_config_optional: 'false',
        npm_config_ignore_scripts: 'true'  // 跳过安装脚本
      };
      
      const { stdout, stderr } = await execAsync(installCommand, {
        cwd: projectPath,
        timeout: 600000, // 10分钟
        env
      });
      
      console.log('✅ 依赖安装完成 (跳过可选依赖)');
      return { success: true, stdout, stderr, method: 'skip' };
      
    } catch (error) {
      console.error('跳过策略安装失败:', error);
      throw error;
    }
  }

  /**
   * 构建项目 (跳过问题依赖)
   */
  async buildWithSkip(projectPath, buildOptions = {}) {
    try {
      console.log('🔨 使用跳过策略构建项目...');
      
      // 读取构建命令
      const packagePath = path.join(projectPath, 'package.json');
      let buildCommand = 'npm run build';
      
      if (await fs.pathExists(packagePath)) {
        const pkg = await fs.readJson(packagePath);
        if (pkg.scripts?.build) {
          buildCommand = 'npm run build';
        }
      }
      
      // 设置构建环境变量
      const buildEnv = {
        ...process.env,
        NODE_ENV: buildOptions.mode || 'production',
        SKIP_PREFLIGHT_CHECK: 'true',
        GENERATE_SOURCEMAP: 'false',  // 跳过源码映射加速构建
        npm_config_optional: 'false',
        SASS_BINARY_SITE: 'https://npmmirror.com/mirrors/node-sass'
      };
      
      const { stdout, stderr } = await execAsync(buildCommand, {
        cwd: projectPath,
        timeout: 900000, // 15分钟
        env: buildEnv
      });
      
      console.log('✅ 项目构建完成 (跳过策略)');
      
      // 检测输出目录
      const outputDirs = ['dist', 'build', 'out'];
      let outputDir = 'dist';
      
      for (const dir of outputDirs) {
        if (await fs.pathExists(path.join(projectPath, dir))) {
          outputDir = dir;
          break;
        }
      }
      
      return {
        success: true,
        outputDir,
        buildMethod: 'skip',
        stdout,
        stderr
      };
      
    } catch (error) {
      console.error('跳过策略构建失败:', error);
      throw error;
    }
  }

  /**
   * 完整的跳过策略构建流程（错误隔离版本）
   */
  async buildProject(projectPath, nodeVersion, envVars, buildOptions) {
    try {
      return await this._performSkipBuild(projectPath, nodeVersion, envVars, buildOptions);
    } catch (error) {
      // 错误隔离：包装并重新抛出，确保不会导致进程意外退出
      const wrappedError = new Error(`Skip构建隔离错误: ${error.message}`);
      wrappedError.originalError = error;
      wrappedError.code = 'SKIP_BUILD';
      throw wrappedError;
    }
  }

  /**
   * 内部跳过策略构建实现
   */
  async _performSkipBuild(projectPath, nodeVersion, envVars, buildOptions) {
    try {
      // 1. 分析问题依赖
      const analysis = await this.analyzeProblematicDeps(projectPath);
      
      if (analysis.hasProblems) {
        console.log(`⚠️  检测到 ${analysis.issues.length} 个问题依赖:`);
        analysis.issues.forEach(issue => {
          console.log(`  - ${issue.name}: ${issue.reason}`);
        });
      }
      
      // 2. 使用依赖冲突解决器进行深度修复
      console.log('🔧 启动依赖冲突解决器...');
      const conflictResolution = await dependencyResolver.resolveAllConflicts(projectPath);
      
      if (conflictResolution.success) {
        console.log('✅ 依赖冲突解决成功:', conflictResolution.message);
      } else {
        console.warn('⚠️  依赖冲突解决失败:', conflictResolution.error);
      }
      
      // 3. 注入环境变量
      if (Object.keys(envVars).length > 0) {
        const envContent = Object.entries(envVars)
          .map(([key, value]) => `${key}=${value}`)
          .join('\n');
        await fs.writeFile(path.join(projectPath, '.env'), envContent);
        console.log(`✅ 已注入 ${Object.keys(envVars).length} 个环境变量`);
      }
      
      // 4. 安装依赖 (使用强制安装)
      await this.installWithForce(projectPath, nodeVersion);
      
      // 5. 构建项目
      const result = await this.buildWithSkip(projectPath, buildOptions);
      
      return result;
      
    } catch (error) {
      console.error('完整构建流程失败:', error);
      throw error;
    }
  }
}

module.exports = new SkipBuildManager();
